<template>
  <div class="pro-table-wrapper">
    <Filter
      v-if="filters && filters.length > 0"
      :filters="filters"
      :custom-id="customId"
      :loading="loading"
      :filter-is-show-all="filterIsShowAll"
      :filter-show-row="filterShowRow"
      @query="onFilterQuery"
      @filter-reset="emit('filter-reset')"
    >
      <!-- Filter 插槽透传 -->
      <template v-for="itemSlot in filterSlots" :key="itemSlot" v-slot:[itemSlot]="temp">
        <slot :name="itemSlot" v-bind="temp"></slot>
      </template>
    </Filter>

    <div class="filter-bottom">
      <slot name="filter-bottom"></slot>
    </div>

    <Table
      ref="TableRef"
      v-bind="attrs"
      :columns="columns"
      :data="data"
      :custom-id="customId"
      v-loading="loading"
    >
      <!-- TableColumn 插槽透传 -->
      <template v-for="itemSlot in tableColumnSlots" :key="itemSlot" v-slot:[itemSlot]="temp">
        <slot :name="itemSlot" v-bind="temp"></slot>
      </template>
    </Table>
    <div class="bottom-content">
      <div class="bottom-before">
        <slot name="table-bottom"></slot>
      </div>

      <Pagination
        v-if="isPage"
        ref="PaginationRef"
        :total="total"
        @query="onPaginationQuery"
      ></Pagination>
    </div>

  </div>
</template>

<script setup lang="ts">
  import '../style/index.scss'
  import { h, ref, useSlots, useAttrs, onMounted } from 'vue'
  import {Table, Filter, FilterItem, getInitFilterParam, Pagination, TableColumnItem, PageParam, getInitPageParam, PageResponse, PAGE_PAGE_NUM_KEY, PAGE_PAGE_SIZE_KEY, PAGE_DATA_KEY, PAGE_TOTAL_KEY} from "@/components"
  import { getProTableFilterSlots, getProTableColumnSlots } from "@/components"
  import { ElTableFns, getElTableFns } from '../../utils/el-table-fn'
  const attrs = useAttrs()
  const slots = useSlots()
  const props = withDefaults(
    defineProps<{
      filters?: FilterItem[]        // 搜索条件
      columns?: TableColumnItem[]   // 列表字段
      getTableData: (params: { [key:string]:any } & PageParam) => PageResponse | Promise<PageResponse> // 获取数据方法
      customId: string,             // 自定义配置的id 区别每个custom
      filterCustom?: boolean        // Filter是否开启搜索条件设置工具
      filterIsShowAll?: boolean     // Filter是否默认展开展示所有搜索条件
      filterShowRow?: number        // Filter默认展示行数
      tableCustom?: boolean         // 是否开启列表字段设置工具
      isPage?: boolean              // 是否展示分页
      drag: {}                      // vue-draggable-plus 组件参数与配置
    }>(),
    {
      filters: () => [],
      columns: () => [],
      customId: () => null,
      filterCustom: true,
      tableCustom: true,
      isPage: true,
      drag: () => null
    }
  )

  const emit = defineEmits<{
    (e: 'filter-reset'),
  }>()

  const TableRef = ref<InstanceType<typeof Table>>()
  const PaginationRef = ref<InstanceType<typeof Pagination>>()
  const filterSlots: string[] = getProTableFilterSlots(props.filters)
  // table的column插槽集合, 插槽字段: TableColumnItem.slot | TableColumnItem.slotHeader
  const tableColumnSlots: string[] = getProTableColumnSlots(props.columns)

  // 加载状态
  const loading = ref<boolean>(false)
  // 搜索条件参数
  const filterParam = ref(getInitFilterParam(props.filters))
  // 分页参数
  const pageParam = ref<PageParam>(getInitPageParam())
  // 列表数据
  const data = ref<any[]>()
  // 总行数
  const total = ref<number>(0)

  /**
   * 查询数据
   */
  const queryData = async () => {
    loading.value = true
    const param = { 
      ...filterParam.value,
      [PAGE_PAGE_NUM_KEY]: pageParam.value.pageNum,
      [PAGE_PAGE_SIZE_KEY]: pageParam.value.pageSize
    }
    let pageResponse:PageResponse
    const pageResult:PageResponse | Promise<PageResponse> = props.getTableData(param)
    if (pageResult instanceof Promise) {
      pageResponse = await pageResult
    } else {
      pageResponse = pageResult
    }
    data.value = pageResponse[PAGE_DATA_KEY]
    total.value = Number(pageResponse[PAGE_TOTAL_KEY])
    loading.value = false
  }
  queryData()


  /**
   * 搜索条件参数变更触发查询事件
   * @param newFilterParam 新的搜索过滤条件参数
   */
  const onFilterQuery = (newFilterParam) => {
    filterParam.value = newFilterParam
    pageParam.value = PaginationRef.value.reset(true)
    queryData()
  }


  /**
   * 分页参数变更触发查询事件
   * @param newPageParam 新的分页参数
   */
  const onPaginationQuery = (newPageParam:PageParam) => {
    pageParam.value = newPageParam
    queryData()
  }


  const expose: any & ElTableFns = {
    refreshData: queryData,
    // element-plus table 方法
    clearSelection: () => null,
    getSelectionRows: () => null,
    toggleRowSelection: () => null,
    toggleAllSelection: () => null,
    toggleRowExpansion: () => null,
    setCurrentRow:  () => null,
  }

  onMounted(() => {
    Object.assign(expose, getElTableFns(TableRef.value))
  })

  defineExpose(expose)

</script>

<style scoped>
</style>
